//*********************************************************
//
//    Copyright (c) Microsoft. All rights reserved.
//    This code is licensed under the Apache License, Version 2.0.
//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************

using System;
using System.ComponentModel;
using SR = Microsoft.Research.DataLayer;
using Microsoft.Research.ScientificWorkflow.TridentUtilities;
using System.Globalization;

namespace Microsoft.Research.ScientificWorkflow.ManagementStudioModels
{
    /// <summary>
    /// A view friendly model for the Workflow.
    /// </summary>
    public class WorkflowViewModel:INotifyPropertyChanged
    {
        #region Private Methods

        /// <summary>
        /// The workflow ID.
        /// </summary>
        private Guid workflowId;

        /// <summary>
        /// The name of the workflow.
        /// </summary>
        private string workflowName;

        /// <summary>
        /// The label for the workflow.
        /// </summary>
        private string versionLabel;

        /// <summary>
        /// Description.
        /// </summary>
        private string description;

        /// <summary>
        /// The author of the workflow.
        /// </summary>
        private string author;

        /// <summary>
        /// The time at which the workflow was created.
        /// </summary>
        private DateTime createdTime;

        /// <summary>
        /// The time at which the workflow was modified.
        /// </summary>
        private DateTime lastModifiedTime;

        /// <summary>
        /// A flag indication if the workflow is deleted.
        /// </summary>
        private bool isDeleted;


        /// <summary>
        /// A flag indication if the workflow can be edited.
        /// </summary>
        private bool canEdit;


        /// <summary>
        /// A flag indication if the workflow can be deleted.
        /// </summary>
        private bool canDelete;


        /// <summary>
        /// The user who deleted the workflow.
        /// </summary>
        private string deletedBy;

        /// <summary>
        /// The time at which the workflow was deleted.
        /// </summary>
        private DateTime deletedTime;


        /// <summary>
        /// The owner ID.
        /// </summary>
        private Guid ownerId;

        #endregion

        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="workflow">The registry workflow object.</param>
        public WorkflowViewModel(SR.Activity workflow)
        {
            this.workflowId = ((SR.IObject)workflow).ID;

            this.workflowName = workflow.Name;
            this.description = workflow.Description;
            this.author = workflow.Created.User;
            this.createdTime = workflow.Created.When;
            this.lastModifiedTime = workflow.Updated.When;
            this.isDeleted = workflow.IsDeleted;
            this.versionLabel = workflow.VersionLabel;
            this.deletedBy = workflow.Updated.User;
            this.deletedTime = workflow.Updated.When;

            if (workflow.Owner != null)
            {
                this.ownerId = ((SR.IObject)workflow.Owner).ID;
            }

            if (TridentAuthentication.LoggedUserRole != UserRole.Admin)
            {
                if (workflow.Security != null)
                {
                    this.canEdit = workflow.Security.Rights.AuthorWorkflow.Check(TridentAuthentication.LoggedInUser);
                }
                if (workflow.Owner.Equals(TridentAuthentication.LoggedInUser))
                {
                    this.canDelete = true;
                }
                else
                {
                    this.canDelete = false;
                }
            }
            else
            {
                this.canEdit = true;
                this.canDelete = true;
            }

            this.Version = workflow.Version.ToString(CultureInfo.CurrentCulture);
        }

        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="workflow">The workflow model.</param>
        public WorkflowViewModel(WorkflowViewModel workflow)
        {
            this.workflowId = workflow.WorkflowId;

            this.workflowName = workflow.WorkflowName;
            this.description = workflow.Description;
            this.author = workflow.Author;
            this.createdTime = workflow.createdTime;
            this.lastModifiedTime = workflow.lastModifiedTime;
            this.isDeleted = workflow.IsDeleted;

            this.deletedBy = workflow.deletedBy;
            this.deletedTime = workflow.deletedTime;
            this.Version = workflow.Version;
            this.versionLabel = workflow.versionLabel;
        }

        #region Public Properties

        /// <summary>
        /// The workflow ID.
        /// </summary>
        public Guid WorkflowId
        {
            get
            {
                return workflowId; 
            }
        }


         /// <summary>
        /// The owner ID.
        /// </summary>
        public Guid OwnerId
        {
            get
            {
                return ownerId; 
            }
        }

        

        /// <summary>
        /// The name of the workflow.
        /// </summary>
        public string WorkflowName
        {
            get
            {
                return workflowName;
            }
            set
            {
                workflowName = value;
                this.OnNotifyPropertyChanged("WorkflowName");
            }
        }

        /// <summary>
        /// The display name of the workflow.
        /// </summary>
        public string Label
        {
            get
            {
                return string.IsNullOrEmpty(this.versionLabel) ? 
                    this.workflowName : string.Format(CultureInfo.InvariantCulture, "{0} ({1})", this.workflowName, this.versionLabel);
            }
        }

        /// <summary>
        ///  Description.
        /// </summary>
        public string Description
        {
            get
            {
                return description;
            }
            set
            {
                description = value;
                this.OnNotifyPropertyChanged("Description");
            }
        }

        /// <summary>
        /// The author of the workflow.
        /// </summary>
        public string Author
        {
            get
            {
                return author;
            }
            set
            {
                author = value;
                this.OnNotifyPropertyChanged("Author");
            }
        }

        /// <summary>
        /// The time at which the workflow was created.
        /// </summary>
        public DateTime CreatedTime
        {
            get
            {
                return createdTime;
            }
            set
            {
                createdTime = value;
            }
        }

        /// <summary>
        /// The time at which the workflow was modified.
        /// </summary>
        public DateTime LastModifiedTime
        {
            get
            {
                return lastModifiedTime;
            }
            set
            {
                lastModifiedTime = value;
            }
        }

        /// <summary>
        ///  A flag indication if the workflow is deleted.
        /// </summary>
        public bool IsDeleted
        {
            get
            {
                return isDeleted;
            }
            set
            {
                isDeleted = value;
                this.OnNotifyPropertyChanged("IsDeleted");
            }
        }

        /// <summary>
        ///  A flag indication if the workflow can be edited.
        /// </summary>
        public bool CanEdit
        {
            get
            {
                return this.canEdit;
            }
            set
            {
                this.canEdit = value;
                this.OnNotifyPropertyChanged("CanEdit");
            }
        }

        /// <summary>
        ///  A flag indication if the workflow can be deleted.
        /// </summary>
        public bool CanDelete
        {
            get
            {
                return this.canDelete;
            }
            set
            {
                this.canDelete = value;
                this.OnNotifyPropertyChanged("CanDelete");
            }
        }

        /// <summary>
        /// The user who deleted the workflow.
        /// </summary>
        public string DeletedBy
        {
            get
            {
                return deletedBy;
            }
            set
            {
                deletedBy = value;
                this.OnNotifyPropertyChanged("DeletedBy");
            }
        }

        /// <summary>
        /// The time at which the workflow was deleted.
        /// </summary>
        public DateTime DeletedTime
        {
            get
            {
                return deletedTime;
            }
            set
            {
                deletedTime = value;
            }
        } 

        /// <summary>
        /// Gets the version of the workflow.
        /// </summary>
        public string Version { get; private set; }
        #endregion

        #region INotifyPropertyChanged Members

        /// <summary>
        /// 
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="propertyName"></param>
        private void OnNotifyPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        #endregion

        /// <summary>
        /// Overridden tostring method. For automation Ids.
        /// </summary>
        /// <returns>The string representation of the object.</returns>
        public override string ToString()
        {
            if (!string.IsNullOrEmpty(this.workflowName))
            {
                return this.workflowName;
            }
            return base.ToString();
        }
    }
}
